package com.lmxdawn.api.admin.service.auth.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.github.pagehelper.PageHelper;
import com.lmxdawn.api.admin.dao.auth.AuthAdminDao;
import com.lmxdawn.api.admin.entity.auth.AuthAdmin;
import com.lmxdawn.api.common.enums.ResultEnum;
import com.lmxdawn.api.admin.exception.JsonException;
import com.lmxdawn.api.admin.req.auth.AuthAdminQueryRequest;
import com.lmxdawn.api.admin.service.auth.AuthAdminService;
import com.lmxdawn.api.common.session.UserSession;
import com.lmxdawn.api.dnf.dto.ExtractReq;
import com.lmxdawn.api.dnf.entity.*;
import com.lmxdawn.api.dnf.service.IChargeConfigService;
import com.lmxdawn.api.dnf.service.impl.ExtraApplyServiceImpl;
import com.lmxdawn.api.dnf.service.impl.RealnameServiceImpl;
import com.lmxdawn.api.dnf.service.impl.UserBillServiceImpl;
import com.lmxdawn.api.dnf.service.impl.WithdrawAccountServiceImpl;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import lombok.var;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Service
public class AuthAdminServiceImpl implements AuthAdminService {

    @Resource
    private AuthAdminDao authAdminDao;
    @Autowired
    private RealnameServiceImpl realnameServiceImpl;

    @Resource
    private IChargeConfigService chargeConfigService;
    @Resource
    private RedissonClient redissonClient;
    @Autowired
    private ExtraApplyServiceImpl extraApplyServiceImpl;
    @Autowired
    private UserBillServiceImpl userBillServiceImpl;
    @Autowired
    private WithdrawAccountServiceImpl withdrawAccountServiceImpl;

    @Override
    public List<AuthAdmin> listAdminPage(AuthAdminQueryRequest authAdminQueryRequest) {
        if (authAdminQueryRequest == null) {
            return Collections.emptyList();
        }
        int offset = (authAdminQueryRequest.getPage() - 1) * authAdminQueryRequest.getLimit();
        PageHelper.offsetPage(offset, authAdminQueryRequest.getLimit());
        return authAdminDao.listAdminPage(authAdminQueryRequest);
    }

    @Override
    public List<AuthAdmin> listAll() {
        return authAdminDao.listAll();
    }

    @Override
    public AuthAdmin findByUserName(String userName) {
        return authAdminDao.findByUserName(userName);
    }

    /**
     * 根据id 获取需要的info
     * @param id
     * @return
     */
    @Override
    public AuthAdmin findById(String id) {
        return authAdminDao.findById(id);
    }

    /**
     * 根据 id 获取密码字段
     * @param id
     * @return
     */
    @Override
    public AuthAdmin findPwdById(String id) {
        return authAdminDao.findPwdById(id);
    }

    /**
     * 新增
     * @param authAdmin
     * @return
     */
    @Override
    public boolean insertAuthAdmin(AuthAdmin authAdmin) {

        if (authAdmin.getUsername() != null) {
            AuthAdmin byUserName = authAdminDao.findByUserName(authAdmin.getUsername());
            if (byUserName != null) {
                throw new JsonException(ResultEnum.DATA_REPEAT, "当前管理员已存在");
            }
        }
        authAdmin.setCreateTime(new Date());
        return authAdminDao.insertAuthAdmin(authAdmin);
    }

    /**
     * 更新
     * @param authAdmin
     * @return
     */
    @Override
    public boolean updateAuthAdmin(AuthAdmin authAdmin) {

        if (authAdmin.getId() == null) {
            return false;
        }
        // 当用户名不为空时，检查是否存在
        if (authAdmin.getUsername() != null) {
            AuthAdmin byUserName = authAdminDao.findByUserName(authAdmin.getUsername());
            // 判断是否存在，剔除自己
            if (byUserName != null && !authAdmin.getId().equals(byUserName.getId())) {
                throw new JsonException(ResultEnum.DATA_REPEAT, "当前管理员已存在");
            }
        }

        return authAdminDao.updateAuthAdmin(authAdmin);
    }
    @Override
    public boolean updateOnlineStatus(String status, String id) {
        return authAdminDao.updateOnlineStatus(status, id );
    }
    /**
     * 根据id删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteById(String id) {
        return authAdminDao.deleteById(id);
    }

    @Override
    public Map queryBalance(UserSession userSession) {
        var admin = authAdminDao.findById(userSession.getId());
        return MapUtil.of("balance", admin.getBalance() == null ? BigDecimal.ZERO : admin.getBalance());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean extractWallet(UserSession userSession, ExtractReq content) throws AlipayApiException {
        // 1、校验 实名
        var admin = authAdminDao.findById(userSession.getId());
        val balanceStr = admin.getBalance();
        var amount = content.getAmount();
        val balance = new BigDecimal(balanceStr);
        if (amount.compareTo(balance) > 0) {
            throw new RuntimeException("提现金额大于可用余额");
        }
        RealName realName = realnameServiceImpl.lambdaQuery().eq(RealName::getUserId, userSession.getId()).one();
        if (realName == null || realName.getStatus() == 0) {
            throw new RuntimeException("请先完成实名认证");
        }
        WithdrawAccount withdrawAccount = withdrawAccountServiceImpl.getById(content.getAccount());
        BigDecimal charge = BigDecimal.ZERO;
        ChargeConfig chargeConfig =
                chargeConfigService.lambdaQuery().eq(ChargeConfig::getType,
                        withdrawAccount.getAccountType().equals("2") ? "A3" // 微信
                                : "A2" // 支付宝
                        ).one();
        if (chargeConfig != null && !"0".equals(chargeConfig.getCharge().trim())) {
            charge = amount.multiply(new BigDecimal(chargeConfig.getCharge()))
                    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
            if (charge.compareTo(BigDecimal.valueOf(2)) < 0) {
                charge = BigDecimal.valueOf(2);
            } else if (charge.compareTo(BigDecimal.valueOf(50)) > 0) {
                charge = BigDecimal.valueOf(50);
            }
        }
        ExtraApply apply = new ExtraApply();
        apply.setAmount(amount);
        apply.setUserId(userSession.getId());
        apply.setFee(charge+"");
        apply.setStatus(0);
        apply.setAccount(content.getAccount());
        extraApplyServiceImpl.save(apply);
        admin.setBalance(balance.subtract(content.getAmount()).toString());
        authAdminDao.updateAuthAdmin(admin);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addWallet(String saleUser, BigDecimal totalAmount, Integer type, String orderId) {
        log.info("=============>addWallet:{}=>{}", saleUser, totalAmount);
        AuthAdmin saler = authAdminDao.findById(saleUser);
        BigDecimal balance = BigDecimal.ZERO;
        if (StrUtil.isNotBlank(saler.getBalance())){
            balance = new BigDecimal(saler.getBalance());
        }
        ChargeConfig chargeConfig = chargeConfigService.lambdaQuery().eq(ChargeConfig::getType, type + "").one();
        if (chargeConfig != null) {
            // 1%  100-1
            BigDecimal charge = totalAmount
                    .multiply(new BigDecimal(chargeConfig.getCharge()))
                    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            if (charge.compareTo(BigDecimal.ONE) < 0){
                charge = BigDecimal.ONE;
            }
            totalAmount = totalAmount.subtract(charge);
        }
        saler.setBalance(String.valueOf(balance.add(totalAmount)));
        authAdminDao.updateAuthAdmin(saler);
        UserBill userBill = new UserBill();
        userBill.setUserId(saleUser);
        userBill.setAmount(totalAmount);
        userBill.setBalance(saler.getBalance());
        userBill.setCreateTime(new Date());
        userBill.setType("订单收入");
        userBill.setRemark("订单id:" + orderId);
        userBillServiceImpl.save(userBill);
    }

    @Override
    public void unbind(String userId) {
        authAdminDao.unbind(userId);
    }

    @Override
    public List<AuthAdmin> listByIds(Collection<?> jimOnlineUser) {
        return authAdminDao.listByIds(jimOnlineUser);
    }

    @Override
    public List<AuthAdmin> listExpireUser() {
        return authAdminDao.listExpireUser();
    }


}
